#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <functional>
#include <cassert>


namespace hsl_log
{
    //buff大小
    #define MAX_BUFFER_SIZE 10*1024*1024//10MB
    //阈值（软上限）
    #define THRESHOLD_BUFFER_SIZE 1024*1024*1024//1024MB
    //增量
    #define INCREMENT_BUFFER_SIZE 10*1024*1024//10MB
    class Buffer
    {
    private:
        size_t _reader_idx;//当前可读数据的指针--本质是下标
        size_t _writer_idx;//当前可写数据的指针--本质是下标
        size_t _capacity;//缓冲区的总容量
        std::vector<char> _buffer;//buffer缓冲区

    public:
        // 构造函数：初始化缓冲区容量（默认10MB）
        Buffer(size_t capacity = MAX_BUFFER_SIZE) 
        : _reader_idx(0), 
        _writer_idx(0),
        _capacity(capacity),
        _buffer(_capacity) {}
        // 判断缓冲区是否已满（写指针是否到达末尾）
        bool full() { return _writer_idx == _capacity; }
        // 判断缓冲区是否为空（读指针是否等于写指针）
        bool empty() { return _reader_idx == _writer_idx; }
        // 获取当前可读数据的大小
        size_t readAbleSize() { return _writer_idx - _reader_idx; }
        // 获取当前可写数据的大小
        size_t writeAbleSize() { return _capacity - _writer_idx; }
        // 重置(初始化  )缓冲区（读写指针归零）
        void reset() { _reader_idx = _writer_idx = 0; }
        // 交换两个缓冲区的所有内容（高效操作）
        void swap(Buffer &buf)
        {
            _buffer.swap(buf._buffer);
            std::swap(_reader_idx, buf._reader_idx);
            std::swap(_writer_idx, buf._writer_idx);
            std::swap(_capacity, buf._capacity);
        }
        // 写入数据到缓冲区
        void push(const char *data, size_t len)
        {
            //阻塞，返回false
            //assert(len <= writeAbleSize());
            //扩容+软限制
            ensure_enough_size(len);
            //把数据拷贝进缓冲区
            std::copy(data, data + len, &_buffer[_writer_idx]);
            //将当前位置向后偏移
            moveWriter(len);
        }
        // 获取当前可读数据的起始地址（用于直接读取）
        const char *begin() { return &_buffer[_reader_idx]; }
        // 从缓冲区移除已读数据（推进读指针）
        void pop(size_t len)
        {   
            moveReader(len);
            assert(_reader_idx <= _capacity);
            if (empty())
                reset();
        }
    private:
        //对写指针进行向后偏移操作
        void moveWriter(size_t len){_writer_idx += len;}
        //对读指针进行向后偏移操作
        void moveReader(size_t len){_reader_idx += len;}
        //确保足够大小
        void ensure_enough_size(size_t len)
        {
            if(len<writeAbleSize())return;
            size_t new_size =0;
            if(_buffer.size()<THRESHOLD_BUFFER_SIZE)
            {
                new_size = _buffer.size()*2+len;//成倍增长
            }
            else
            {
                new_size = _buffer.size()+INCREMENT_BUFFER_SIZE+len;//线性增长
                //return false;//到软限制就返回false阻塞
            }
            _buffer.reserve(new_size);
        }
    };
}